//=====================================================================
//
//  File:      BulkCopyWithFormat.cpp
//  Summary:   This sample shows how to create a bulk copy format file.
// 
//             Assumes the following TSQL has been run:
//             use AdventureWorks
//             CREATE TABLE BCPDate (cola int, colb datetime)
//             insert BCPDate(cola) values(1) 
//             insert BCPDate(cola) values(2) 
//             insert BCPDate(cola) values(3) 
//             insert BCPDate(cola) values(4)
// 
//  Date:      December 23, 2005     
//
//---------------------------------------------------------------------
//
//  This file is part of the Microsoft SQL Server Code Samples.
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation.  See these other
//materials for detailed information regarding Microsoft code samples.
//
//THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF 
//ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
//THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//
//===================================================================== 

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>

SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC;  

void Cleanup() {
   if (hdbc1 != SQL_NULL_HDBC) {
      SQLDisconnect(hdbc1);
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
   }

   if (henv != SQL_NULL_HENV)
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
}

int main() {
   RETCODE retcode;

   // BCP variables.
   SDWORD cRows;

   // Allocate the ODBC environment and save handle.
   retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLAllocHandle(Env) Failed\n\n");
      Cleanup();
      return(9);
   }

   // Notify ODBC that this is an ODBC 3.0 app.
   retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
      Cleanup();
      return(9);    
   }

   // Allocate ODBC connection handle, set bulk copy mode, and connect.
   retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLAllocHandle(hdbc1) Failed\n\n");
      Cleanup();
      return(9);
   }

   retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP, (void *)SQL_BCP_ON, SQL_IS_INTEGER);
   if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
      printf("SQLSetEnvAttr(ODBC version) Failed\n\n");
      Cleanup();
      return(9);    
   }

   // Sample uses Integrated Security, create SQL Server DSN using Windows NT authentication. 
   retcode = SQLConnect(hdbc1, (UCHAR*)"AdventureWorks", SQL_NTS, (UCHAR*)"",SQL_NTS, (UCHAR*)"", SQL_NTS);
   if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
      printf("SQLConnect() Failed\n\n");
      Cleanup();
      return(9);
   }

   // Initialize the bulk copy.
   retcode = bcp_init(hdbc1, "BCPDate", "BCPODBC.bcp", NULL, DB_OUT);
   if (retcode != SUCCEED) {
      printf("bcp_init() Failed\n\n");
      Cleanup();
      return(9);
   }

   // Set the number of output columns.
   retcode = bcp_columns(hdbc1, 2);
   if (retcode != SUCCEED) {
      printf("bcp_init() Failed\n\n");
      Cleanup();
      return(9);
   }

   // Describe the format of column 1 in the data file.
   retcode = bcp_colfmt(hdbc1, 1, SQLCHARACTER, -1, 5, NULL, 0, 1);
   if (retcode != SUCCEED) {
      printf("bcp_init() Failed\n\n");
      Cleanup();
      return(9);
   }

   // Describe the format of column 2 in the data file.
   retcode = bcp_colfmt(hdbc1, 2, SQLCHARACTER, -1, 20, NULL, 0, 2);
   if (retcode != SUCCEED) {
      printf("bcp_init() Failed\n\n");
      Cleanup();
      return(9);
   }

   // Create the format file.
   retcode = bcp_writefmt(hdbc1, "c:\\BCPFMT.fmt");
   if (retcode != SUCCEED) {
      printf("bcp_init() Failed\n\n");
      Cleanup();
      return(9);
   }

   // Execute the bulk copy.
   retcode = bcp_exec(hdbc1, &cRows);
   if (retcode != SUCCEED) {
      printf("bcp_init() Failed\n\n");
      Cleanup();
      return(9);
   }

   printf("Number of rows bulk copied out = %d.\n", cRows);

   // Cleanup
   SQLDisconnect(hdbc1);
   SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
   SQLFreeHandle(SQL_HANDLE_ENV, henv);
   return(0);
}